package com.shengsiyuan.netty.thirdexample;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * Created by deng_wb on 2019/8/1
 */
public class MyChatServerHandler extends SimpleChannelInboundHandler<String> {

    /** 保存客户端的channel连接对象 **/
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel(); // 向服务端发送数据的客户端连接
        channelGroup.forEach(ch->{
            if (ch!=channel){
                ch.writeAndFlush(channel.remoteAddress()+ "发送的消息: "+msg+"\r\n");
            }else{
                ch.writeAndFlush(" [自己] "+msg+"\n");
            }
        });

    }

    /** 连接一旦建立的回调 **/
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("[服务器] - "+channel.remoteAddress()+" 加入\n");
        channelGroup.add(channel);
    }

    /** 连接一旦断掉的回调 **/
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("[服务器] - "+channel.remoteAddress()+" 离开\n");
        // 连接一旦断掉,netty会自动将channelGroup中断掉的channel移除
        System.out.println(channelGroup.size());
    }

    /** 表示连接属于活动状态 **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress()+" 上线");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress()+" 下线");    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
